/*
 *  \file KBServer.h
 *  GRE
 *
 *  Created by Kutlak Roman on 24/01/2012.
 *  Copyright 2012 Kutlak Roman. All rights reserved.
 *
 */

#ifndef KBServer_h 
#define KBServer_h

#include <netinet/in.h>

#include "KnowledgeBase.h"
#include "ServerUtils.h"

namespace kutlak {
namespace roman {
namespace gre {
    
#define BUFFER_SIZE 2048
    /*!
     * \brief A KB server that allows a client to get entities over a network.
     */
    class KBServer { 
    public: 
#pragma mark -
#pragma mark lifecycle
        
        KBServer(const std::string& paht = "", size_t port = 9734);
        
        KBServer(KBServer& from) = delete;
        KBServer& operator=(KBServer from) = delete;
        
        virtual ~KBServer(void);
        
#pragma mark -
#pragma mark operations
        void Run();
        
        void Exit();
        
        void AddFile(const std::string& path);
        
        void Entities(int clientSocket);
        
        void EntitiesWithProperty(int clientSocket);
        
        void EntitiesOfType(int clientSocket);
        
        void EntityById(int clientSocket);
        
        void EntityByName(int clientSocket);

#pragma mark -
#pragma mark data
        
    protected:
        void Send(int socket, const std::vector<Entity>& entities);
        void SendString(int socket, const std::string& str) const;

    private:
        bool fExit;
        int mSocket;
        unsigned int mAddressLen;
        struct sockaddr_in mAddress;
        pKnowledgeBase mpKnowledgeBase;
    };
    
    Property ReadProperty(int clientSocket);
    std::string ReadString(int clientSocket);
    
    void* ServeClient(void* data);
    
    struct ServerInfo {
        ServerInfo(int socket = -1, KBServer* ptr = NULL) : 
        socket_(socket), serverPtr_(ptr) {}
        
        int socket_;
        KBServer* serverPtr_;
    };
    
    struct SocketException {
        SocketException(int s) : socket_(s) {}
        int socket_;
    };
    
} // end namespace GRE
}
}
#endif // KBServer_h
